home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / conf / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-03-13  |  19.6 KB

  1. Subject:  v13i099:  Multi-user conferencing system, Part02/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Keith Gabryelski <ag@crash.cts.com>
  7. Posting-number: Volume 13, Issue 99
  8. Archive-name: conf/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #! /bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create the files:
  15. #    conf.h
  16. #    confalloc.c
  17. #    config.h
  18. #    confopts.c
  19. export PATH; PATH=/bin:$PATH
  20. if test -f 'conf.h'
  21. then
  22.     echo shar: will not over-write existing file "'conf.h'"
  23. else
  24. cat << \SHAR_EOF > 'conf.h'
  25. /*
  26.  *    conf - An interactive multi-user chat program.
  27.  *
  28.  *    conf Copyright (c) 1986, 1987 by Keith Gabryelski
  29.  *
  30.  *    Conf is quasi-public domain software; it may be used and copied
  31.  *    freely and may be modified to suit the indivuals needs as long
  32.  *    as:
  33.  *
  34.  *    [1] It is not sold.
  35.  *    [2] It is not made part of any licensed product.
  36.  *    [3] This header and others like it are not modified or removed.
  37.  *    [4] You allow others to use and copy without charge.
  38.  *    
  39.  *    without expressed written permission from the original
  40.  *    author (Keith Gabryelski).
  41.  *
  42.  */
  43.  
  44. #include "config.h"
  45. #include <stdio.h>
  46. #include <sys/types.h>
  47. #include <ctype.h>
  48. #include <signal.h>
  49. #include <sys/stat.h>
  50. #include <pwd.h>
  51. #include <setjmp.h>
  52. #include <errno.h>
  53.  
  54. #ifdef    SYSV
  55. #include <unistd.h>
  56. #include <termio.h>
  57. #include <fcntl.h>
  58. #endif    SYSV
  59.  
  60. #ifdef    BSD
  61. #include <sgtty.h>
  62. #include <sys/ioctl.h>
  63. #include <sys/file.h>
  64.  
  65. #define    index    strchr
  66. #define    rindex    strrchr
  67. #endif    BSD
  68.  
  69.  
  70. #include "structs.h"
  71. #include "extern.h"
  72.  
  73. /*
  74.  * some ASCII values
  75.  *
  76.  */
  77.  
  78. #ifdef    CTRL
  79. #undef    CTRL
  80. #endif    CTRL
  81. #define    CTRL(c)        ('c'&0x1F)
  82. #define    BELL        0x07
  83. #define    BS        0x08
  84. #define    TAB        0x09
  85. #define    LF        0x0A
  86. #define    CR        0x0D
  87. #define    DEL        0x7F
  88.  
  89. /*
  90.  * some bools
  91.  *
  92.  */
  93.  
  94. #ifdef    TRUE
  95. #undef    TRUE
  96. #endif    TRUE
  97. #define    TRUE    1
  98.  
  99. #ifdef    FALSE
  100. #undef    FALSE
  101. #endif    FALSE
  102. #define    FALSE    0
  103.  
  104. #define    NEXTWORD    1
  105. #define    THEREST        2
  106.  
  107. #define    NOVIS        0
  108. #define    VIS        1
  109.  
  110. #define    forever        for ever
  111. #define    ever        (;;)
  112. SHAR_EOF
  113. fi # end of overwriting check
  114. if test -f 'confalloc.c'
  115. then
  116.     echo shar: will not over-write existing file "'confalloc.c'"
  117. else
  118. cat << \SHAR_EOF > 'confalloc.c'
  119. /*
  120.  *    conf - An interactive multi-user chat program.
  121.  *
  122.  *    conf Copyright (c) 1986, 1987 by Keith Gabryelski
  123.  *
  124.  *    Conf is quasi-public domain software; it may be used and copied
  125.  *    freely and may be modified to suit the indivuals needs as long
  126.  *    as:
  127.  *
  128.  *    [1] It is not sold.
  129.  *    [2] It is not made part of any licensed product.
  130.  *    [3] This header and others like it are not modified or removed.
  131.  *    [4] You allow others to use and copy without charge.
  132.  *    
  133.  *    without expressed written permission from the original
  134.  *    author (Keith Gabryelski).
  135.  *
  136.  */
  137.  
  138. #include "conf.h"
  139.  
  140. /*
  141.  *    memory managment stuff.
  142.  */
  143.  
  144. char *
  145. mymalloc(size)
  146. unsigned size;
  147. {
  148.     char *p;
  149.  
  150.     if ((p = malloc(size)) == NULL)
  151.     {
  152.     (void)fprintf(stderr, "%s: Out of memory.\n", progname);
  153.     nice_exit(-1);
  154.     }
  155.  
  156.     return p;
  157. }
  158.  
  159. char *
  160. myrealloc(p, size)
  161. char *p;
  162. unsigned size;
  163. {
  164.     if (p == NULL)
  165.     {
  166.     if ((p = malloc(size)) == NULL)
  167.     {
  168.         (void)fprintf(stderr, "%s: Out of memory.\n", progname);
  169.         nice_exit(-1);
  170.     }
  171.     }
  172.     else if ((p = realloc(p, size)) == NULL)
  173.     {
  174.     (void)fprintf(stderr, "%s: Out of memory.\n", progname);
  175.     nice_exit(-1);
  176.     }
  177.  
  178.     return p;
  179. }
  180. SHAR_EOF
  181. fi # end of overwriting check
  182. if test -f 'config.h'
  183. then
  184.     echo shar: will not over-write existing file "'config.h'"
  185. else
  186. cat << \SHAR_EOF > 'config.h'
  187. /*
  188.  *    conf - An interactive multi-user chat program.
  189.  *
  190.  *    conf Copyright (c) 1986, 1987 by Keith Gabryelski
  191.  *
  192.  *    Conf is quasi-public domain software; it may be used and copied
  193.  *    freely and may be modified to suit the indivuals needs as long
  194.  *    as:
  195.  *
  196.  *    [1] It is not sold.
  197.  *    [2] It is not made part of any licensed product.
  198.  *    [3] This header and others like it are not modified or removed.
  199.  *    [4] You allow others to use and copy without charge.
  200.  *    
  201.  *    without expressed written permission from the original
  202.  *    author (Keith Gabryelski).
  203.  *
  204.  */
  205.  
  206. /*
  207.  * System type.  Define only the *ONE* system that applies to you
  208.  * the most.
  209.  */
  210.  
  211. #define SYSV                /* System V and Xenix.  SCO Xenix */
  212. /*#define BSD                /* Any of the Berkeley clan */
  213.  
  214. /*
  215.  *  Define MYCRYPT only if you do not have working encrypt() or setkey()
  216.  *  system calls.  Some system do not come with crypt because of oversea's
  217.  *  laws.
  218.  *
  219.  *  Some systems have a broken encrypt() system call (3b1, and SCO Xenix)
  220.  *
  221.  *  The crypt functions supplied by me are BOGUS.  If you have a public
  222.  *  domain crypt that I may include with later releases, please email a
  223.  *  copy to: ag@portnoy.cts.com or crash!portnoy!ag@nosc.mil
  224.  *
  225.  *  If you *DO NOT* define MYCRYPT and conference messages look somewhat
  226.  *  like line noise, then your encrypt function will not work with conf.
  227.  *  You must then, define MYCRYPT and re-make conf.
  228.  *
  229.  */
  230.  
  231. #define MYCRYPT        /* Use my crypt function? */
  232.  
  233. /*
  234.  * Define USE_TERMCAP if you have the termcap library.  conf will work
  235.  * without termcap.  I include it to figure out the users terminal clear
  236.  * screen string.  The clear screen string can be defined in your CONFOPTS
  237.  * environment variable, .confrc, or at any time during conf.
  238.  *
  239.  * If you define this variable remember to include "-lcurses", "-ltermcap",
  240.  * or "-ltermlib" in the Makefile.
  241.  *
  242.  */
  243.  
  244. #define    USE_TERMCAP         /* Use-p TERMCAP */
  245.  
  246. /*
  247.  * Define SENDER as the local command to use to SEND a message.
  248.  * :rings will popen() this command giving it one user on the
  249.  * command line and its message through standard input.
  250.  *
  251.  * If you do not have a local SEND program then define this as
  252.  * "write".
  253.  */
  254.  
  255. #define SENDER    "write"        /* the local send program */
  256.  
  257. /*
  258.  * The default pager
  259.  *    maybe "more" or "cat"
  260.  */
  261.  
  262. #define    DEF_PAGER    "less"        /* local pager */
  263. #define    DEF_SHELL    "csh"        /* default shell*/
  264.  
  265. /*
  266.  * User settable files.
  267.  *    Someday these files will be definable at any time during conf
  268.  */
  269.  
  270. #define    CONFLOG        "/usr/lib/conf/conflog"   /* conversation log */
  271. #define    CONFUSERS    "/usr/lib/conf/confusers" /* user log */
  272. #define    CONFHELP    "/usr/lib/conf/confhelp"  /* help file */
  273.  
  274. #define    DEF_RECFILE    "conf.rec"     /* default record file */
  275. #define    CONFRC        ".confrc"     /* default rc file */
  276.  
  277. #define    CONFOPTS    "CONFOPTS"          /* evironment variable */
  278.  
  279. #define    NUMBER_OF_THE_BEAST    0666
  280. #define    FILEMASK    NUMBER_OF_THE_BEAST /* filemask for CONF{USERS,LOG} */
  281.  
  282. /* Some buffer length stuff */
  283. #define    MAXNAMELEN    21
  284. #define    MAXTTYLEN    21
  285. #define    MAXCONFLINES    100     /* number of conference lines */
  286.  
  287. #define    PAGESIZ        512     /* alloc this amount at a time */
  288.  
  289. /*
  290.  * DEF_CLSSTR is a default clear screen string.  It will be used if
  291.  * conf cannot figure out your terminal (using TERMCAP) and the user
  292.  * does set the clear screen string to something different.
  293.  *
  294.  * It is currently set to the ANSI clear screen string.  You may
  295.  * want to set it to "\n" for no action.
  296.  *
  297.  */
  298.  
  299. #define    DEF_CLS        "\033[2J\033[H"  /* default clear screen screen */
  300. #define DEF_COLUMNS    80
  301. #define DEF_LINES    24
  302. #define TABAGE        2        /* space between columns */
  303.  
  304. /*
  305.  * The public key is used for normal messages, sends, replies, and informs
  306.  * if another password is not given.
  307.  *
  308.  * Passwords are 8 characters or less.
  309.  */
  310.  
  311. #define    MAXPASSWORDLEN    8
  312. #define DEF_KEY        "Pax"         /* default public key */
  313.  
  314. /*
  315.  * Some important influences.
  316.  *
  317.  * Thanks should also go out to Neil Pert for awesome percussion. -MQH
  318.  */
  319.  
  320. #define SIGNIFICANT_OTHER    "Marla Gabryelski"
  321.  
  322. #define    MUSICIAN        "Brian_Eno"
  323. #define    SONG            "Third_Uncle"
  324.  
  325. #define VERNUM            1
  326. #define PATCHLEVEL        0
  327.  
  328. #define AUTHOR            "Keith M. Gabryelski"
  329. #define ADDRESS            "ag@portnoy.cts.com"
  330. #define ALTPATH            "ag@crash.cts.com"
  331. #define THANKS1            "ford@kenobi.cts.com (Mike Ditto)"
  332. #define    THANKS2            "paul@portnoy.cts.com (Paul Palacios)"
  333.  
  334. /*
  335.  * form strings
  336.  *
  337.  *    Meta characters for form string:
  338.  *
  339.  *    %N - Your conference name.
  340.  *    %n - Name of user sending message.
  341.  *    %m - Message users sent.
  342.  *    %T - Your tty.
  343.  *    %t - Tty of user that sent message.
  344.  *    %% - The character '%'
  345.  *
  346.  */
  347.  
  348. #define    DEF_FORM_NORM    ";;; %n (%t) - %m\n"
  349. #define    DEF_FORM_SEND    ">>> %n (%t) - %m\n"
  350. #define    DEF_FORM_INFORM    "::: %n (%t) [%m]\n"
  351. #define    DEF_FORM_LINE    "::: %n (%t) - %m\n"
  352. #define    DEF_FORM_SHOUT    "*** %n (%t) - %m\n"
  353.  
  354. /*
  355.  * DEBUGx are debugging defines.
  356.  *
  357.  */
  358.  
  359. #define DEBUG0        /* insignificant checks around conf */
  360. /*#define DEBUG1        /* temporary debug messages */
  361. /*#define DEBUG2        /* dealing with crypt and block functions */
  362. /*#define DEBUG3        /* another temporary */
  363. SHAR_EOF
  364. fi # end of overwriting check
  365. if test -f 'confopts.c'
  366. then
  367.     echo shar: will not over-write existing file "'confopts.c'"
  368. else
  369. cat << \SHAR_EOF > 'confopts.c'
  370. /*
  371.  *    conf - An interactive multi-user chat program.
  372.  *
  373.  *    conf Copyright (c) 1986, 1987 by Keith Gabryelski
  374.  *
  375.  *    Conf is quasi-public domain software; it may be used and copied
  376.  *    freely and may be modified to suit the indivuals needs as long
  377.  *    as:
  378.  *
  379.  *    [1] It is not sold.
  380.  *    [2] It is not made part of any licensed product.
  381.  *    [3] This header and others like it are not modified or removed.
  382.  *    [4] You allow others to use and copy without charge.
  383.  *    
  384.  *    without expressed written permission from the original
  385.  *    author (Keith Gabryelski).
  386.  *
  387.  */
  388.  
  389. #include "conf.h"
  390.  
  391. int set_name(), set_integer(), set_ptrstr();
  392.  
  393. #ifdef    USE_TERMCAP
  394. char *ocls;
  395. int use_ocap, ocol, olin;
  396. #endif    USE_TERMCAP
  397.  
  398. gettcap()
  399. {
  400.     char *ptr;
  401.  
  402. #ifdef    USE_TERMCAP
  403.     char buf[1024];
  404.  
  405.     use_ocap = FALSE;
  406.     if (tgetent(buf, getenv("TERM")) == 1)
  407.     {
  408.     columns=tgetnum("co");
  409.     lines=tgetnum("li");
  410.     tcapstr("cl", &cls);
  411.     use_ocap= TRUE;
  412.     ocol = columns;
  413.     olin = lines;
  414.     ocls = mymalloc(strlen(cls)+1);
  415.     (void) strcpy(ocls, cls);
  416.     }
  417. #endif    USE_TERMCAP
  418.  
  419.     if ((ptr = getenv("COLUMNS")) != NULL)
  420.     columns = atoi(ptr);
  421.  
  422.     if ((ptr = getenv("LINES")) != NULL)
  423.     lines = atoi(ptr);
  424.  
  425.     if ((ptr = getenv("CLS")) != NULL)
  426.     {
  427.     cls = myrealloc(cls, strlen(ptr)+1);
  428.     (void) strcpy(cls, ptr);
  429.     }
  430.  
  431.     if ((ptr = getenv("SHELL")) != NULL)
  432.     {
  433.     shell = myrealloc(shell, strlen(ptr)+1);
  434.     (void) strcpy(shell, ptr);
  435.     }
  436.  
  437.     if ((ptr = getenv("PG")) != NULL)
  438.     {
  439.     pager = myrealloc(pager, strlen(ptr)+1);
  440.     (void) strcpy(pager, ptr);
  441.     }
  442. }
  443.  
  444. getrc()
  445. {
  446.     char *fname;
  447.     char tmp[100];
  448.     char *bp, *p;
  449.     int c;
  450.     FILE *fp;
  451.  
  452.     if (homedir == NULL)
  453.     {
  454.     (void)fprintf(stderr, "%s: Can't figure you out!  Not using %s.\n",
  455.         progname, CONFRC);
  456.     return;
  457.     }
  458.  
  459.     fname = mymalloc((unsigned)(strlen(homedir) + 1 + strlen(CONFRC) + 1));
  460.  
  461.     (void)strcpy(fname, homedir);
  462.     (void)strcat(fname, "/");
  463.     (void)strcat(fname, CONFRC);
  464.  
  465.     if ((fp = fopen(fname, "r")) == (FILE *)NULL)
  466.     {
  467.         if (errno != ENOENT)
  468.         (void)fprintf(stderr, "%s: Couldn't open confrc file %s (%s).\n",
  469.         progname, fname, puterr(errno));
  470.  
  471.     free(fname);
  472.     return;
  473.     }
  474.  
  475.     forever
  476.     {
  477.     p = bp = tmp;
  478.  
  479.     while (((c = getc(fp)) != EOF) && (c != '\n'))
  480.         *p++ = c;
  481.  
  482.     if (c == EOF)
  483.         break;
  484.  
  485.     *p = '\0';
  486.  
  487.     while (isspace(*bp))
  488.         bp++;
  489.  
  490.     if ((*bp == '#') || (*bp == ';') || (*bp == '\0'))
  491.         continue;
  492.  
  493.     if (*bp == ':')        /* a colon command? */
  494.     {
  495.         linelen = strlen(bp+1);
  496.         if (!intpret(bp+1))
  497.         {
  498.         (void) printf("Invalid confrc line in %s @\"%s\".\n",fname,bp);
  499.         return;
  500.         }
  501.     }
  502.     else
  503.     {
  504.         if ((bp = parsestr(bp, p-bp, NEXTWORD)) == NULL)
  505.         continue;
  506.  
  507.         do
  508.         {
  509.         if ((c = setopts(bp)) != FOUNDOPT)
  510.         {
  511.             if (c == AMBIGUOUS)
  512.             (void)fputs("Ambiguous", stdout);
  513.             else
  514.             (void)fputs("Invalid", stdout);
  515.  
  516.             (void)printf(" confrc file %s @\"%s\"\n", fname, bp);
  517.             free(fname);
  518.             return;
  519.         }
  520.         } while ((bp = parsestr((char *)NULL, 0, NEXTWORD)) != NULL);
  521.     }
  522.     }
  523.  
  524.     free(fname);
  525.  
  526.     (void)fclose(fp);
  527. }
  528.  
  529. getopts()
  530. {
  531.     char *ptr;
  532.     int x;
  533.  
  534. #ifdef    USE_TERMCAP
  535.     if (use_ocap)
  536.     {
  537.     columns= ocol;
  538.     lines=olin;
  539.     cls = myrealloc(cls, strlen(ocls)+1);
  540.     (void) strcpy(cls, ocls);
  541.     free(ocls);
  542.     }
  543. #endif    USE_TERMCAP
  544.  
  545.     if ((ptr = getenv("COLUMNS")) != NULL)
  546.     columns = atoi(ptr);
  547.  
  548.     if ((ptr = getenv("LINES")) != NULL)
  549.     lines = atoi(ptr);
  550.  
  551.     if ((ptr = getenv("CLS")) != NULL)
  552.     {
  553.     cls = myrealloc(cls, strlen(ptr)+1);
  554.     (void) strcpy(cls, ptr);
  555.     }
  556.  
  557.     if ((ptr = getenv("SHELL")) != NULL)
  558.     {
  559.     shell = myrealloc(shell, strlen(ptr)+1);
  560.     (void) strcpy(shell, ptr);
  561.     }
  562.  
  563.     if ((ptr = getenv("PAGER")) != NULL)
  564.     {
  565.     pager = myrealloc(pager, strlen(ptr)+1);
  566.     (void) strcpy(pager, ptr);
  567.     }
  568.  
  569.     if ((ptr = getenv(CONFOPTS)) != NULL)
  570.     {
  571.     ptr = parsestr(ptr, strlen(ptr), NEXTWORD);
  572.  
  573.     do
  574.     {
  575.         if ((x = setopts(ptr)) != FOUNDOPT)
  576.         {
  577.         if (x == AMBIGUOUS)
  578.             (void)fputs("Ambiuous", stdout);
  579.         else
  580.             (void)fputs("Invalid", stdout);
  581.  
  582.         (void)printf(" %s environment variable @%s\n", CONFOPTS, ptr);
  583.         break;
  584.         }
  585.     } while ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL);
  586.     }
  587. }
  588.  
  589. setopts(opt)
  590. char *opt;
  591. {
  592.     int found;
  593.  
  594.     static struct varopts vartab[] =
  595.     {
  596.     { "askdump", BOOLEAN|DISPLAY, &askdump, TRUE, },
  597.     { "noaskdump", BOOLEAN|DISPLAY, &askdump, FALSE, },
  598.     { "!askdump", BOOLEAN|NODISPLAY, &askdump, FALSE, },
  599.     { "autowho", BOOLEAN|DISPLAY, &autowho, TRUE, },
  600.     { "noautowho", BOOLEAN|DISPLAY, &autowho, FALSE, },
  601.     { "!autowho", BOOLEAN|NODISPLAY, &autowho, FALSE, },
  602.     { "banner", BOOLEAN|DISPLAY, &banner, TRUE, },
  603.     { "nobanner", BOOLEAN|DISPLAY, &banner, FALSE, },
  604.     { "!banner", BOOLEAN|NODISPLAY, &banner, FALSE, },
  605.     { "beep", BOOLEAN|DISPLAY, &beep, TRUE, },
  606.     { "nobeep", BOOLEAN|DISPLAY, &beep, FALSE, },
  607.     { "!beep", BOOLEAN|NODISPLAY, &beep, FALSE, },
  608.     { "columns", NUMBER|DISPLAY, &columns, 0, set_integer, },
  609.     { "cls", STRING|DISPLAY, (int *)&cls, POINTER, set_ptrstr, },
  610.     { "expand8bit", BOOLEAN|DISPLAY, &expand8bit, TRUE, },
  611.     { "noexpand8bit", BOOLEAN|DISPLAY, &expand8bit, FALSE, },
  612.     { "!expand8bit", BOOLEAN|NODISPLAY, &expand8bit, FALSE, },
  613.     { "expandctrl", BOOLEAN|DISPLAY, &expandctrl, TRUE, },
  614.     { "noexpandctrl", BOOLEAN|DISPLAY, &expandctrl, FALSE, },
  615.     { "!expandctrl", BOOLEAN|NODISPLAY, &expandctrl, FALSE, },
  616.     { "inform-format", STRING|DISPLAY, (int *)&informform, POINTER, set_ptrstr, },
  617.     { "line", NUMBER|DISPLAY, &cuser.cu_line, 0, do_to, },
  618.     { "line-format", STRING|DISPLAY, (int *)&lineform, POINTER, set_ptrstr, },
  619.     { "lines", NUMBER|DISPLAY, &lines, 0, set_integer, },
  620.     { "lineinput", BOOLEAN|DISPLAY, &lineinput, TRUE, },
  621.     { "nolineinput", BOOLEAN|DISPLAY, &lineinput, FALSE, },
  622.     { "nolineinput", BOOLEAN|DISPLAY, &lineinput, FALSE, },
  623.     { "!lineinput", BOOLEAN|NODISPLAY, &lineinput, FALSE, },
  624.     { "name", STRING|DISPLAY, (int *)cuser.cu_cname, ROUTINE, set_name, },
  625.     { "normal-format", STRING|DISPLAY, (int *)&normform, POINTER, set_ptrstr, },
  626.     { "pager", STRING|DISPLAY, (int *)&pager, POINTER, set_ptrstr, },
  627.     { "password", STRING|NODISPLAY, (int *)curpass, ROUTINE, set_pass, },
  628.     { "recfile", STRING|DISPLAY, (int *)&recfile, POINTER, set_ptrstr, },
  629.     { "seeme", BOOLEAN|DISPLAY, &seeme, TRUE, },
  630.     { "noseeme", BOOLEAN|DISPLAY, &seeme, FALSE, },
  631.     { "!seeme", BOOLEAN|NODISPLAY, &seeme, FALSE, },
  632.     { "seemyinform", BOOLEAN|DISPLAY, &informe, TRUE, },
  633.     { "noseemyinform", BOOLEAN|DISPLAY, &informe, FALSE, },
  634.     { "!seemyinform", BOOLEAN|NODISPLAY, &informe, FALSE, },
  635.     { "send-format", STRING|DISPLAY, (int *)&sendform, POINTER, set_ptrstr, },
  636.     { "shell", STRING|DISPLAY, (int *)&shell, POINTER, set_ptrstr, },
  637.     { "shout-format", STRING|DISPLAY, (int *)&shoutform, POINTER, set_ptrstr, },
  638.     { "warncrypt", BOOLEAN|DISPLAY, &warncrypt, TRUE, },
  639.     { "nowarncrypt", BOOLEAN|DISPLAY, &warncrypt, FALSE, },
  640.     { "!warncrypt", BOOLEAN|NODISPLAY, &warncrypt, FALSE, },
  641.     { NULL, }
  642.     }, *varptr, *keepptr;
  643.  
  644.     if (opt == NULL)
  645.     {
  646.     char *string;
  647.     int tmp;
  648.     int len=0;
  649.  
  650.     for (varptr = vartab; varptr->name != NULL; varptr++)
  651.         if ((varptr->type == BOOLEAN) && (*varptr->var == varptr->extra))
  652.         if ((tmp = strlen(varptr->name)) > len)
  653.             len = tmp;
  654.  
  655.     len += TABAGE;
  656.  
  657.     (void)fputs("Boolean flags:\n\n", stdout);
  658.  
  659.     for (varptr = vartab; varptr->name != NULL; varptr++)
  660.         if ((varptr->type == BOOLEAN) && (*varptr->var == varptr->extra))
  661.         colprnt(varptr->name, len);
  662.  
  663.     terpri();
  664.  
  665.     len = 0;
  666.  
  667.     for (varptr = vartab; varptr->name != NULL; varptr++)
  668.         if (varptr->type == NUMBER)
  669.         if ((tmp = strlen(varptr->name)+1+declen(varptr->var)) > len)
  670.             len = tmp;
  671.  
  672.     len += TABAGE;
  673.  
  674.     (void)fputs("\nNumeric options:\n\n", stdout);
  675.  
  676.     string = mymalloc((unsigned)(len+1));
  677.     for (varptr = vartab; varptr->name != NULL; varptr++)
  678.         if (varptr->type == NUMBER)
  679.         {
  680.         (void) sprintf(string, "%s=%d", varptr->name, *varptr->var);
  681.         colprnt(string, len);
  682.         }
  683.  
  684.     terpri();
  685.  
  686.     len = 0;
  687.  
  688.     for (varptr = vartab; varptr->name != NULL; varptr++)
  689.         if (varptr->type == STRING)
  690.         if (varptr->extra&POINTER)
  691.         {
  692.             if ((tmp=strlen(varptr->name)+vislen(*varptr->var)+3) > len)
  693.             len = tmp;
  694.         }
  695.         else
  696.         {
  697.             if ((tmp= strlen(varptr->name)+vislen(varptr->var)+3) > len)
  698.             len = tmp;
  699.         }
  700.  
  701.     len += TABAGE;
  702.  
  703.     (void)fputs("\nString options:\n\n", stdout);
  704.  
  705.     string = myrealloc(string, (unsigned)(len+1));
  706.     for (varptr = vartab; varptr->name != NULL; varptr++)
  707.         if (varptr->type == STRING)
  708.         {
  709.         if (varptr->extra&POINTER)
  710.             (void) sprintf(string, "%s=\"%s\"", varptr->name,
  711.                 *varptr->var);
  712.         else
  713.             (void) sprintf(string, "%s=\"%s\"", varptr->name,
  714.                 varptr->var);
  715.         colprnt(string, len);
  716.         }
  717.  
  718.     terpri();
  719.     free(string);
  720.  
  721.     return FOUNDOPT;
  722.     }
  723.  
  724.     keepptr = (struct varopts *)NULL;
  725.     found = 0;
  726.     for (varptr = vartab; varptr->name != NULL; varptr++)
  727.     if (!strncmp(varptr->name, opt, strlen(opt)))
  728.     {
  729.         if (!found)
  730.         keepptr = varptr;
  731.  
  732.         if (found >= 0)
  733.         ++found;
  734.  
  735.         if (strlen(varptr->name) == strlen(opt))
  736.         {
  737.         found = -1;
  738.         keepptr = varptr;
  739.         }
  740.     }
  741.  
  742.     if (!found)
  743.     return NOOPT;
  744.  
  745.     if (found > 1)
  746.     return AMBIGUOUS;
  747.  
  748.     switch(keepptr->type&VARMASK)
  749.     {
  750.     case BOOLEAN:
  751.         *keepptr->var = keepptr->extra;
  752.         break;
  753.  
  754.     case NUMBER:
  755.         return (*keepptr->var_func)(keepptr->name, keepptr->var);
  756.  
  757.     case STRING:
  758.         return (*keepptr->var_func)(keepptr->name, keepptr->var);
  759.  
  760.     default:
  761.         return NOOPT;
  762.     }
  763.  
  764.     return FOUNDOPT;
  765. }
  766.  
  767. set_name()
  768. {
  769.     char *ptr, *ptr2;
  770.     char nbuf[20+MAXNAMELEN];
  771.  
  772.     if ((ptr = ptr2 = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
  773.     {
  774.     if (confing)
  775.     {
  776.         (void) printf("name = \"%s\"\n", cuser.cu_cname);
  777.         return TRUE;
  778.     }
  779.  
  780.     return FALSE;
  781.     }
  782.  
  783.     while(*ptr2 != '\0')
  784.     {
  785.     if ((*ptr2 > ' ') && !strchr(",:/", *ptr2))
  786.         ptr2++;
  787.     else
  788.         *ptr2 = '\0';
  789.     }
  790.  
  791.     if (*ptr == '\0')
  792.     {
  793.     if (confing)
  794.     {
  795.         (void)puts("Invalid name given.");
  796.         return TRUE;
  797.     }
  798.  
  799.     return FALSE;
  800.     }
  801.  
  802.     (void) sprintf(nbuf, "Changed name from %s", cuser.cu_cname);
  803.  
  804.     (void) strncpy(cuser.cu_cname, ptr, MAXNAMELEN);
  805.     cuser.cu_cname[MAXNAMELEN-1] = '\0';
  806.     clog.f_usrlen = strlen(cuser.cu_cname) + 1;
  807.  
  808.     if (confing)
  809.     {
  810.     write_log(INFORM, nbuf, (char *)NULL, 0, (unsigned)strlen(nbuf));
  811.     write_usr();
  812.     (void)printf("Name changed to \"%s\"\n", cuser.cu_cname);
  813.     }
  814.  
  815.     return TRUE;
  816. }
  817.  
  818. set_integer(name, var)
  819. char *name;
  820. int *var;
  821. {
  822.     char *ptr;
  823.  
  824.     if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL)
  825.     *var = atoi(ptr);
  826.  
  827.     (void) printf("%s = %d\n", name, *var);
  828.     return FOUNDOPT;
  829. }
  830.  
  831. set_ptrstr(name, var)
  832. char *name, **var;
  833. {
  834.     char *ptr;
  835.  
  836.     if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL)
  837.     {
  838.     *var = myrealloc(*var, strlen(ptr)+1);
  839.     (void) strcpy(*var, ptr);
  840.     }
  841.  
  842.     (void) printf("%s = \"", name);
  843.     visprnt(*var, stdout);
  844.     (void) puts("\"");
  845.  
  846.     return FOUNDOPT;
  847. }
  848.  
  849. declen(num)
  850. register int num;
  851. {
  852.     register int places = 1;
  853.  
  854.     while ((num /= 10) >= 1)
  855.     ++places;
  856.  
  857.     return places;
  858. }
  859.  
  860. tcapstr(string, var)
  861. char *string, **var;
  862. {
  863.     char *tcapbuf = mymalloc(1024);
  864.     char *tmp = tcapbuf;
  865.  
  866.     (void) tgetstr(string, &tmp);
  867.     *var = realloc(*var, tmp-tcapbuf);
  868.     (void) strcpy(*var, tcapbuf);
  869.     free(tcapbuf);
  870. }
  871. SHAR_EOF
  872. fi # end of overwriting check
  873. #    End of shell archive
  874. exit 0
  875.  
  876.